// 该文件用于创建Vuex中最为核心的store

// 重点：创建store实例之前，必须需要引入Vuex，且使用Vuex插件才可以，否则报错，所以将该语句写到该文件里面。
import Vue from 'vue'
// 引入vuex，其中Vuex也可以小写为vuex，大小写都支持。
// 重点：引入Vuex，用于创建store对象
import Vuex from 'vuex';
// 使用Vuex插件，一旦引入Vuex的话，创建Vue的vm的时候，就可以传入一个store配置项了。
Vue.use(Vuex);// 这里使用Vue进行use的话，需要提前引入Vue的。

// // 引入Vuex，用于创建store对象
// import Vuex from 'vuex'; 

// 1、准备actions，用于响应组件中的动作
const actions = {
    // increment: function () {
    //     console.log('Actions里面的increment 被调用了！');
    // }

    // // 使用es6中对象的简写形式，可以省略冒号:function()。
    // increment(context, value) {
    //     // 参数一是一个mini版本的Store，命名为context，意味着上下文。
    //     // 参数二就是传递的参数值。
    //     console.log('Actions里面的 increment 被调用了！', context, value);
    //     // 此处的Action调用commit，走到Mutations
    //     context.commit('INCREMENT', value);
    // },

    // // 使用es6中对象的简写形式，可以省略冒号:function()。
    // decrement(context, value) {
    //     // 参数一是一个mini版本的Store，命名为context，意味着上下文。
    //     // 参数二就是传递的参数值。
    //     console.log('Actions里面的 decrement 被调用了！', context, value);
    //     // 此处的Action调用commit，走到Mutations
    //     context.commit('DECREMENT', value);
    // },

    // 使用es6中对象的简写形式，可以省略冒号:function()。
    incrementOdd(context, value) {
        // 参数一是一个mini版本的Store，命名为context，意味着上下文。
        // 参数二就是传递的参数值。
        console.log('Actions里面的 incrementOdd 被调用了！', context, value);
        // 此处的Action调用commit，走到Mutations
        if (context.state.sum % 2) {
            context.commit('INCREMENT', value)
        }
    },

    // 使用es6中对象的简写形式，可以省略冒号:function()。
    incrementWait(context, value) {
        // 参数一是一个mini版本的Store，命名为context，意味着上下文。
        // 参数二就是传递的参数值。
        console.log('Actions里面的 incrementWait 被调用了！', context, value);
        // 此处的Action调用commit，走到Mutations
        setTimeout(() => {
            context.commit('INCREMENT', value)
        }, 500)
    }

}

// 2、准备mutations，用于操作数据（state）
// 规则约束：其中Action里面的方法是小写，Mutations里面的方法名称是大写的。
// 语法约束：Mutations里面不要再写任何业务逻辑和发送Ajax请求了。
const mutations = {
    // 自定义快捷键：
    // 转换为大写：Ctrl + Alt + U
    // 转换为小写：Ctrl + Alt + L
    INCREMENT(state, value) {
        // 参数一是state，且这个state是一个对象，此处检测数据改变的原理和vue是一样的。
        // 参数二value，就是传递的参数值
        console.log('Mutations里面的 INCREMENT 被调用了！', state, value);
        state.sum += value;
    },

    DECREMENT(state, value) {
        // 参数一是state，且这个state是一个对象，此处检测数据改变的原理和vue是一样的。
        // 参数二value，就是传递的参数值
        console.log('Mutations里面的 DECREMENT 被调用了！', state, value);
        state.sum -= value;
    },

    // INCREMENTODD(state, value) {
    //     // 参数一是state，且这个state是一个对象，此处检测数据改变的原理和vue是一样的。
    //     // 参数二value，就是传递的参数值
    //     console.log('Mutations里面的 INCREMENTODD 被调用了！', state, value);
    //     state.sum += value;
    // },

    // INCREMENTWAIT(state, value) {
    //     // 参数一是state，且这个state是一个对象，此处检测数据改变的原理和vue是一样的。
    //     // 参数二value，就是传递的参数值
    //     console.log('Mutations里面的 INCREMENTWAIT 被调用了！', state, value);
    //     state.sum += value;
    // }

    ADD_PERSON(state, value) {
        console.log('mutations中的ADD_PERSON被调用了')
        state.personList.unshift(value);
    }
}

// 3、准备state，用于存储数据
const state = {
    sum: 0,// 当前的和
    school: '尚硅谷',
    subject: 'Vue2 && Vue3',
    personList: [
        { id: '001', name: '张三' }
    ]
}

// 当state中的数据需要经过加工后再使用时，可以使用getters加工。在store.js中追加getters配置
// 准备getters，用于将staet中的数据进行加工。
const getters = {
    // 可以使用对象的简写形式
    // bigSum:function(state) {
    //     return state.sum * 10;
    // },

    // 参数是state
    bigSum(state) {
        return state.sum * 10;
    }
}

// 其中store里面的staet、getters类似与Vue里面的data、computed。

// 4、创建store对象，创建store对象的目的就是管理actions、mutations、state
const store = new Vuex.Store({
    // 对象的名称和值一样的话，可以触发对象的简写形式
    actions: actions,
    mutations: mutations,
    state: state,
    getters: getters, // getters也是store的全新配置项。
});

// 5、对外暴露(导出)，使用默认暴露store
export default store;

// 简写形式，创建并暴露store
// export default new Vuex.Store({
//     // 对象的名称和值一样的话，可以触发对象的简写形式
//     actions: actions,
//     mutations: mutations,
//     state: state
// });
